#pragma once

#include "WVector.h"
#include <vector>

class WVTree;

class WVNode
{
public:
	WVNode(WVTree* tree, WVNode* parent, unsigned level);
	~WVNode();

	bool Find(const WVector& point, float threshold, WVector& result) const;
	bool FindAll(const WVector& point, float threshold, std::vector<WVector>& results) const;

	size_t GetNumNodes() const;
	size_t GetNumWords() const;
	size_t GetMaxWords() const;

protected:
	void Insert(const WVector& vector);
	bool FindImpl(const WVector& point, float threshold, WVector& result) const;
	bool FindAllImpl(const WVector& point, float threshold, std::vector<WVector>& results) const;
	
	WVTree* tree_;
	WVNode* parent_;
	unsigned level_;
	WVNode* negtive_;
	WVNode* positive_;
	std::vector<WVector> vectors_;
};

class WVTree : public WVNode
{
public:
	WVTree(unsigned maxLevels, float margin = 0.05);
	~WVTree()
	{		
	}

	void SetVectors(const std::vector<WVector>& vectors);

	unsigned GetMaxLevels() const
	{
		return maxLevels_;
	}

	float GetMargin() const
	{
		return margin_;
	}

	void Report();

private:
	unsigned maxLevels_;
	float margin_;
};
